package com.leyou.search.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.client.ItemClient;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.dto.*;
import com.leyou.search.pojo.Goods;
import com.leyou.search.repository.GoodsRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndexService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private GoodsRepository goodsRepository;

    public Goods buildGoods(SpuDTO spu){
        Goods goods = BeanHelper.copyProperties(spu, Goods.class);
        //0.categoryId
        goods.setCategoryId(spu.getCid3());

        //2.createTime
        goods.setCreateTime(spu.getCreateTime().getTime());

        //3.all
        List<Long> categoryIds = spu.getCategoryIds();
        List<CategoryDTO> categoryDTOS = this.itemClient.queryCategoryByIds(categoryIds);
        String names = categoryDTOS.stream().map(CategoryDTO::getName).collect(Collectors.joining(" "));
        goods.setAll(spu.getName()+" "+names);

        //4.skus
        List<SkuDTO> skuDTOS = this.itemClient.querySkuBySpuId(spu.getId());
        List<Map<String,Object>> skuMaps = new ArrayList<>();
        Set<Long> skuPrice=new HashSet<>();

        skuDTOS.forEach(skuDTO -> {

            skuPrice.add(skuDTO.getPrice());

            Map<String, Object> skuMap = new HashMap<>();
            skuMap.put("id",skuDTO.getId());
            skuMap.put("title",skuDTO.getTitle());
            skuMap.put("price",skuDTO.getPrice());
            skuMap.put("image", StringUtils.isNotBlank(skuDTO.getImages())?skuDTO.getImages().split(",")[0]:"");

            skuMaps.add(skuMap);
        });
        goods.setSkus(JsonUtils.toString(skuMaps));

        //5.price
        goods.setPrice(skuPrice);

        //6.specs 所有可搜索的规格参数
        Map<String, Object> specs = new HashMap<>();
        List<SpecParamDTO> specParamDTOS = this.itemClient.querySpecParams(null, spu.getCid3(), true);

        SpuDetailDTO spuDetailDTO = this.itemClient.querySpuDetailById(spu.getId());
        Map<Long,Object> genericSpec=JsonUtils.nativeRead(spuDetailDTO.getGenericSpec(), new TypeReference<Map<Long, Object>>() {
        });
        Map<Long,List<String>> specialSpec=JsonUtils.nativeRead(spuDetailDTO.getSpecialSpec(), new TypeReference<Map<Long, List<String>>>() {
        });


        Object value=null;
        for(SpecParamDTO specParamDTO:specParamDTOS){
            Long id = specParamDTO.getId();
            String name = specParamDTO.getName();
            if(specParamDTO.getGeneric()){
                value=genericSpec.get(id);
            }else {
                value=specialSpec.get(id);
            }

            if(specParamDTO.getNumeric()){
                value=chooseSegment(value,specParamDTO);
            }


            specs.put(name,value);

        }

        goods.setSpecs(specs);


        return goods;
    }

    private String chooseSegment(Object value, SpecParamDTO p) {
        if (value == null || StringUtils.isBlank(value.toString())) {
            return "其它";
        }
        double val = parseDouble(value.toString());
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = parseDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if (segs.length == 2) {
                end = parseDouble(segs[1]);
            }
            // 判断是否在范围内
            if (val >= begin && val < end) {
                if (segs.length == 1) {
                    result = segs[0] + p.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segs[1] + p.getUnit() + "以下";
                } else {
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }

    private double parseDouble(String str) {
        try {
            return Double.parseDouble(str);
        } catch (Exception e) {
            return 0;
        }
    }

    public void createIndex(Long id) {
        SpuDTO spuDTO = itemClient.querySpuById(id);
        Goods goods = buildGoods(spuDTO);
        this.goodsRepository.save(goods);
    }

    public void deleteById(Long id) {
        goodsRepository.deleteById(id);
    }
}
